
//HAL

//BSP
#include "lib/button.h"
//OS
#include "jxos_public.h"

static JXOS_EVENT_HANDLE button_press_event;

static swtime_type button_scan_swt;
static swtime_type button_multi_click_swt;

static uint8_t button_msg_buff[32];
static JXOS_MSG_HANDLE button_msg;

static uint8_t button_multi_click_count;
static uint8_t button_multi_click_keynum;

static BUTTON_GROUP_STRUCT button_g;
static BUTTON_STRUCT button_space[BUTTON_TASK_BUTTON_NUM_MAX];

void (*std_app_button_task_hal_init_callback)(void) = 0;
uint8_t (*std_app_button_task_hal_read_button_state_callback)(uint8_t button_num) = 0;

void std_app_button_task_button_press_interrupt_handler(void)
{
	jxos_event_set(button_press_event);
}

static uint8_t button_all_release_check(void)
{
	uint8_t i;
    for(i = 0; i < BUTTON_TASK_BUTTON_NUM_MAX; i++){
		if(std_app_button_task_hal_read_button_state_callback(i) == BUTTON_PRESS){
			break;
		}
    }
	if(i < BUTTON_TASK_BUTTON_NUM_MAX){
		return 0;
	}
	else{
		return 1;
	}
}

static void button_task(uint8_t task_id, void * parameter)
{
	BUTTON_MSG_STRUCT msg_itme;
	if(jxos_event_wait(button_press_event) == 1){
		sys_svc_software_timer_restart(button_scan_swt);
		button_group_scan_tick_handler(&button_g, 1);
		if(button_all_release_check() == 1){
			sys_svc_software_timer_stop(button_scan_swt);
		}
	}
	if(sys_svc_software_timer_check_overtime(button_scan_swt) == 1){
		button_group_scan_tick_handler(&button_g, 1);
		if(button_all_release_check() == 1){
			sys_svc_software_timer_stop(button_scan_swt);
		}
	}
	if(sys_svc_software_timer_check_overtime(button_multi_click_swt) == 1){
		sys_svc_software_timer_stop(button_multi_click_swt);
		if(button_all_release_check() == 1){
			msg_itme.button_num = button_multi_click_keynum;
			msg_itme.multi_click_count = button_multi_click_count;
			jxos_msg_send(button_msg, &msg_itme);
		}
		button_multi_click_count = 0;
		button_multi_click_keynum = 0xff;
	}
}

/******************************/
static uint8_t button_st_to_button_num(BUTTON_STRUCT* button)
{
    uint8_t i;
    for(i = 0; i < BUTTON_TASK_BUTTON_NUM_MAX; i++){
        if(button == &(button_space[i])){
            break;
        }
    }
    if(i == BUTTON_TASK_BUTTON_NUM_MAX){
        i = 0xff;
    }
    return i;
}

static void button_task_button_press_callback_handler(BUTTON_STRUCT* button)
{
	uint8_t button_num = button_st_to_button_num(button);
	if(button_num != 0xff){
		sys_svc_software_timer_restart(button_multi_click_swt);
		if(button_multi_click_keynum != button_num){
			button_multi_click_count = 0;
			button_multi_click_keynum = button_num;
		}
		button_multi_click_count++;
	}
}

static void button_task_button_long_press_callback_handler(BUTTON_STRUCT* button)
{
	BUTTON_MSG_STRUCT msg_itme;
	uint8_t button_num = button_st_to_button_num(button);
	if(button_num != 0xff){
		msg_itme.button_num = button_num;
		msg_itme.multi_click_count = 0;
		jxos_msg_send(button_msg, &msg_itme);
	}
}

static uint8_t std_app_button_task_hal_read_button_state_callback_handelr(BUTTON_STRUCT* button)
{
	uint8_t button_num;
	if(std_app_button_task_hal_read_button_state_callback != 0){
		button_num = button_st_to_button_num(button);
		if(button_num != 0xff){
			button_num = std_app_button_task_hal_read_button_state_callback(button_num);
		}
		else{
			button_num = BUTTON_RELEASE;
		}
	}
	else{
		button_num = BUTTON_RELEASE;
	}

	return button_num;
}

/******************************/
void std_app_button_task_init(void)
{
	uint8_t i;
	button_multi_click_count = 0;
	button_multi_click_keynum = 0xff;

	//HAL
	if(std_app_button_task_hal_init_callback != 0){
		std_app_button_task_hal_init_callback();
	}


	button_group_init(&button_g, BUTTON_TASK_BUTTON_NUM_MAX, button_space);
    for(i = 0; i < BUTTON_TASK_BUTTON_NUM_MAX; i++){
        button_new(&button_g, 0, BUTTON_TASK_LONG_PRESS_TICK, BUTTON_TASK_LONG_PRESS_TICK,
					std_app_button_task_hal_read_button_state_callback_handelr,
					button_task_button_press_callback_handler,
					0,
					button_task_button_long_press_callback_handler);
    }

	//OS
	jxos_task_create(button_task, "button", 0);
	button_press_event = jxos_event_create();
    button_msg = jxos_msg_create(button_msg_buff, 32, 1, "std_app_button_msg");

	//LIB

	//SYS TASK
	button_scan_swt = sys_svc_software_timer_new();
	sys_svc_software_timer_set_time(button_scan_swt, BUTTON_TASK_SCAN_TICK_TIME);

	button_multi_click_swt = sys_svc_software_timer_new();
	sys_svc_software_timer_set_time(button_multi_click_swt, BUTTON_TASK_MULTI_CLICK_TIME);
}


